<template>
    <div>
        <!-- 播放器容器 -->
        <div playsrc="playsrc" ref="playerContainer" class="player-container"></div>
        <!-- 提示信息 -->
        <div v-if="message" class="message">{{ message }}</div>
    </div>
</template>

<script>
import Player, { Popover } from "nplayer"; // 引入 NPlayer 和 Popover
import Hls from "hls.js"; // 引入 hls.js

export default {
    name: "HlsPlayer",
    props: {
        playsrc:{
            type: String,
            default: ''
        }
    },
    data() {
        return {
            player: null, // 用于保存 NPlayer 实例
            hls: null, // 用于保存 hls.js 实例
            message: "", // 提示信息
            limitTime: 3, // 限制播放时间（单位：秒）
        };
    },
    mounted() {
        this.initPlayer(this.playsrc); // 初始化播放器
    },
    methods: {
        initPlayer(playsrc) {
            // 1. 创建一个控制条项
            const Quantity = {
                el: document.createElement("div"),
                init() {
                    this.btn = document.createElement("div");
                    this.btn.textContent = "画质";
                    this.el.appendChild(this.btn);
                    this.popover = new Popover(this.el);
                    this.btn.addEventListener("click", () =>
                        this.popover.show()
                    );
                    // 点击按钮的时候展示 popover
                    this.el.style.display = "none"; // 默认隐藏
                    this.el.classList.add("quantity");
                },
            };

            // 2. 初始化 NPlayer 实例
            this.player = new Player({
                controls: [
                    [
                        "play",
                        "volume",
                        "time",
                        "spacer",
                        Quantity,
                        "airplay",
                        "settings",
                        "web-fullscreen",
                        "fullscreen",
                    ],
                    ["progress"],
                ],
                // 覆盖默认小屏布局为空
                bpControls: {},
            });

            // 3. 创建 HLS 实例
            this.hls = new Hls();
            this.hls.on(Hls.Events.MEDIA_ATTACHED, () => {
                this.hls.on(Hls.Events.MANIFEST_PARSED, () => {
                    // 4. 给清晰度排序，清晰度越高的排在最前面
                    this.hls.levels.sort((a, b) => b.height - a.height);
                    const frag = document.createDocumentFragment();

                    // 5. 给与清晰度对应的元素添加，点击切换清晰度功能
                    const listener = (i) => (init) => {
                        const last = Quantity.itemElements[ Quantity.itemElements.length - 1 ];
                        const prev = Quantity.itemElements[Quantity.value] || last;
                        const el = Quantity.itemElements[i] || last;
                        prev.classList.remove("quantity_item-active");
                        el.classList.add("quantity_item-active");
                        Quantity.btn.textContent = el.textContent;
                        if (init !== true && !this.player.paused) {
                            setTimeout(() => this.player.play());
                        }
                        // 因为 HLS 切换清晰度会使正在播放的视频暂停，我们这里让它再自动恢复播放
                        Quantity.value = this.hls.currentLevel = this.hls.loadLevel = i;
                        Quantity.popover.hide();
                    };

                    // 6. 添加清晰度对应元素
                    Quantity.itemElements = this.hls.levels.map((l, i) => {
                        const el = document.createElement("div");
                        el.textContent = l.name + "P";
                        if (l.height === 1080) el.textContent += " 高清";
                        if (l.height === 720) el.textContent += "  清晰";
                        el.classList.add("quantity_item");
                        el.addEventListener("click", listener(i));
                        frag.appendChild(el);
                        return el;
                    });

                    const el = document.createElement("div");
                    el.textContent = "自动";
                    el.addEventListener("click", listener(-1));
                    el.classList.add("quantity_item");
                    frag.appendChild(el);
                    Quantity.itemElements.push(el);
                    // 这里再添加一个 `自动` 选项，HLS 默认是根据网速自动切换清晰度

                    Quantity.popover.panelEl.appendChild(frag);
                    Quantity.el.style.display = "block";

                    listener(this.hls.currentLevel)(true); // 初始化当前清晰度
                });

                // 绑定 video 元素成功的时候，去加载视频
                this.hls.loadSource(playsrc);
            });

            this.hls.attachMedia(this.player.video); // 绑定 video 元素
            this.player.mount(this.$refs.playerContainer); // 挂载播放器

            // 监听播放事件（只播放3秒）
            this.player.video.addEventListener("timeupdate", this.onTimeUpdate);
        },

        onTimeUpdate() {
            const currentTime = this.player.video.currentTime;
            if (currentTime >= this.limitTime) {
                this.player.video.pause(); // 暂停视频
                this.message = `视频已播放 ${this.limitTime} 秒，播放结束`;
                console.log(this.message);
                this.player.video.removeEventListener("timeupdate", this.onTimeUpdate); // 移除监听
            }
        }

    },
    beforeDestroy() {
        // 销毁播放器和 hls.js 实例
        if (this.player) {
            this.player.destroy();
        }
        if (this.hls) {
            this.hls.destroy();
        }
    },
};
</script>

<style>
.player-container {
    width: 100%;
    max-width: 800px;
    margin: 0 auto;
}

.quantity {
    position: relative;
    padding: 0 8px;
    cursor: pointer;
    font-size: 14px;
    font-weight: bold;
    white-space: nowrap;
    opacity: 0.8;
}
.quantity:hover {
    opacity: 1;
}
.quantity_item {
    padding: 5px 20px;
    font-weight: normal;
}
.quantity_item:hover {
    background: rgba(255, 255, 255, 0.3);
}
.quantity_item-active {
    color: var(--theme-color);
}

.message {
    margin-top: 10px;
    font-size: 16px;
    color: #333;
    text-align: center;
}
</style>
